<template>
  <div>
    <el-form ref="form" :model="formData" :rules="rules" label-width="120px">
      <template v-for="(item, index) in formList">
        <el-form-item
          :key="`${item.prop}${index}`"
          :style="item.itemStyle || {}"
          :label="item.name"
          :prop="item.prop"
          :class="item.itemClass"
        >
          <component
            :is="item.componentType || 'el-input'"
            :style="item.style || {}"
            :value-format="item.valueFormat || {}"
            v-if="item.prop !== 'relationDataTypes'"
            v-model="formData[item.prop]"
            :clearable="true"
            :class="item.class"
            v-bind="item.attrConfig || {}"
            @change="handlerSelectData(item)"
          >
            <template v-for="option in item.optionList">
              <el-radio v-if="item.componentType === 'el-radio-group'" :label="option.value">{{ option.label }}
              </el-radio>
            </template>
          </component>
          <el-checkbox v-if="item.prop === 'relationDataTypes'"
                       v-model="formData['relationDataType_' + option.value]"
                       :disabled="formData.activityType == null"
                       @change="(selected) => relationDataTypesChange(option,selected)"
                       v-for="option in item.optionList" :label="option.label" :key="option.value">{{ option.label }}
          </el-checkbox>
        </el-form-item>
      </template>
      <div v-for="item in relationDataTypeList" class="relation-data-container">
        <div class="relation-item">
          <div class="relation-title">{{ item.title }}</div>
          <div class="relation-data">
            <el-row>
              <el-col :span="8">
                <el-form-item label="所属项目" required label-position="left" label-width="90">
                  <el-select placeholder="请选择项目" v-model="formData['relationSceneProject_' + item.value]"
                             @change="(value) => relationProjectChangeHandler(item,value)">
                    <el-option v-for="projectItem in projectList" :key="projectItem.id"
                               :value="projectItem.id" :label="projectItem.projectName" />
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="所属场景" required label-position="left" label-width="90">
                  <el-cascader placeholder="请选择所属场景" :props="{'multiple' : true,'checkStrictly': true}"
                               @change="(value) => relationRoomChangeHandler(item,value)"
                               v-model="formData['relationSceneRoom_' + item.value]"
                               :options="roomInfo[formData['relationSceneProject_' + item.value]]">
                  </el-cascader>
                </el-form-item>
              </el-col>
              <el-col :span="8" v-if="item.value === '1'">
                <el-form-item label="设备名称" required label-position="left" label-width="90">
                  <el-select placeholder="请选择设备名称" multiple
                             @change="(values) => relationDeviceChangeHandler(item,values)"
                             v-model="formData['relationDevice_' + item.value]">
                    <el-option v-for="deviceItem in deviceInfo[item.value]" :key="deviceItem.id" :value="deviceItem.id"
                               :label="deviceItem.deviceName"></el-option>
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="8" v-else-if="item.value === '2'">
                <el-form-item label="绿化名称" required label-position="left" label-width="90">
                  <el-select placeholder="请选择绿化" multiple
                             @change="(values) => relationCarbonSinkDataChangeHandler(item,values)"
                             v-model="formData['relationDevice_' + item.value]">
                    <el-option v-for="deviceItem in deviceInfo[item.value]" :key="deviceItem.id" :value="deviceItem.id"
                               :label="deviceItem.typeName"></el-option>
                  </el-select>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row :span="24" class="row-title" v-show="item.list.length > 0">
              <el-col :span="4">所属项目</el-col>
              <el-col :span="4">所属场景</el-col>
              <template v-if="item.value === '1'">
                <el-col :span="4">设备编号</el-col>
                <el-col :span="4">设备名称</el-col>
                <el-col :span="4">能源名称</el-col>
                <el-col :span="3">统计类型</el-col>
              </template>
              <template v-else-if="item.value === '2'">
                <el-col :span="4">绿化名称</el-col>
                <el-col :span="11">种植方式</el-col>
              </template>
              <el-col :span="1"></el-col>
            </el-row>
            <el-row :span="24" v-for="(dataItem,index) in item.list" :key="index" class="row-item">
              <el-col :span="4">{{ dataItem.sceneProjectName }}</el-col>
              <el-col :span="4">{{ dataItem.fullRoomName }}</el-col>
              <template v-if="item.value === '1'">
                <el-col :span="4">{{ dataItem.deviceCode }}</el-col>
                <el-col :span="4">{{ dataItem.deviceName }}</el-col>
                <el-col :span="4">{{ dataItem.meterTypeName }}</el-col>
                <el-col :span="3">{{ dataItem.staticsTypeName }}</el-col>
              </template>
              <template v-else-if="item.value === '2'">
                <el-col :span="4">{{ dataItem.typeName }}</el-col>
                <el-col :span="11">{{ dataItem.carbonSinkName }}</el-col>
              </template>
              <el-col :span="1">
                <el-button type="danger" icon="el-icon-delete" size="mini"
                           @click="relationDeviceDeleteHandler(item,dataItem)" />
              </el-col>
            </el-row>
          </div>
        </div>
      </div>
    </el-form>
  </div>
</template>

<script>
import { dictMixin } from '@/mixin/dict'
import api from '@/api/apis/sceneRoom'
import { parseSceneData } from '@/utils/scene-data'

export default {
  name: 'AddActivityCarbonEmission',
  mixins: [dictMixin],
  props: {
    // 请求参数
    requestParams: {
      type: Object,
      default: () => ({})
    },
    // 弹窗数据
    popData: {
      type: Object,
      default: () => ({})
    },
    // 弹窗配置
    popConfig: {
      type: Object,
      default: () => ({})
    },
    // 弹窗取消
    close: {
      type: Boolean,
      default: false
    },
    // 弹窗确认
    confirm: {
      type: Boolean,
      default: false
    }
  },
  created() {
    this.processDetail = false;
    this.$api.sceneProject.queryProjectList({}).then(res => {
      this.projectList = res.data
    })
  },
  data() {
    return {
      isAdd: true,
      processDetail: false,
      projectList: [],
      roomInfo: {},
      deviceInfo: {},
      formData: {
        relationDataTypes: [],
        relationDataOthers: false,
        activityType: null
      },
      relationDataTypeList: [],
      maxRemarkLength: 200,
      formList: [
        {
          name: '活动名称',
          prop: 'activityName',
          attrConfig: { placeholder: '请输入活动名称' }
        },
        {
          name: '活动类型',
          prop: 'activityType',
          componentType: 'el-radio-group',
          optionList: [],
          selectPath: 'commonSelected',
          selectParams: {
            code: 'ActivityCarbonEmissionType'
          },
          dataProp: {
            dataType: 'resData',
            nameProp: 'label',
            codeProp: 'value'
          },
          attrConfig: {
            placeholder: '请选择活动类型',
            style: { width: '60%' },
            options: []
          }
        },
        {
          name: '备注',
          prop: 'remarks',
          componentType: 'el-input',
          attrConfig: {
            type: 'textarea',
            placeholder: '请输入备注',
            autosize: {
              minRows: 3,
              maxRows: 6
            }
          },
          style: { width: '100%' }
        }, {
          name: '关联数据项',
          prop: 'relationDataTypes',
          optionList: [],
          selectPath: 'commonSelected',
          selectParams: {
            code: 'ActivityCarbonEmissionDataType'
          },
          dataProp: {
            dataType: 'resData',
            nameProp: 'label',
            codeProp: 'value'
          },
          attrConfig: {
            placeholder: '请选择关联数据项',
            style: { width: '60%' },
            options: []
          }
        }
      ]
    }
  },
  computed: {
    rules() {
      return {
        activityName: [
          { required: true, message: '请输入活动名称', trigger: 'blur' },
          { max: 50, message: '活动名称最长50字符', trigger: 'blur' }
        ],
        activityType: [{ required: true, message: '请选择活动类型', trigger: 'blur' }],
        rangeRemark: [
          { required: false, max: 200, message: '说明不超过200字', trigger: 'blur' }
        ]
      }
    }
  },
  watch: {
    popData: {
      handler(data) {
        this.isAdd = !data.id
        this.formList.forEach((e) => {
          this.$set(this.formData, e.prop, data[e.prop])
        })
        this.$set(this.formData, 'id', data.id)
        if (data.id) {
          this.formList[1].attrConfig.disabled = true
        }
      },
      deep: true,
      immediate: true
    },
    formList: {
      handler(data) {
        if (data[3].optionList.length > 0 && this.formData.id && !this.processDetail) {
          this.loadingDetail(this.formData.id)
        }
      },
      deep: true,
      immediate: true
    },
    confirm() {
      const params = {
        ...(this.formData || {})
      }
      this.submit(params)
    }
  },
  methods: {
    async loadingDetail(id) {
      if(this.processDetail){
        return; //标记每次编辑时，此方法只调用一次，不然会死循环.因为watch的是 formList ，而这个方法中又会修改 formList中一些属性。
      }
      this.processDetail = true;
      const res = await this.$api.activityCarbonEmission.detail(id)
      const formData = res.data
      if (formData.activityType === '1' && this.formList[3].optionList?.length > 0) {
        this.formList[3].optionList = this.formList[3].optionList.filter(item => item.value !== '2') // 修改 formList中一些属性。
      }
      formData['relationDataType_3'] = (formData.relationDataOthers === true)
      const relationDataObj = {}
      formData.relationData.forEach(item => {
        if (!relationDataObj[item.dataType]) {
          relationDataObj[item.dataType] = []
        }
        relationDataObj[item.dataType].push(item)
      })
      this.formData = formData
      for (const key in relationDataObj) {
        const valueList = relationDataObj[key]
        this.formData['relationDataType_' + key] = true
        let relationData = this.formList[3].optionList.find(item => item.value === key);
        if(!relationData) {
          continue;
        }
        await this.relationDataTypesChange(relationData, true)
        this.formData['relationSceneProject_' + key] = valueList[0].sceneProjectId
        await this.relationProjectChangeHandler(relationData, valueList[0].sceneProjectId)
        this.formData['relationSceneRoom_' + key] = valueList.map(item => {
          const relationSceneRooms = []
          if (item.sceneEdificeId) {
            relationSceneRooms.push(item.sceneEdificeId)
          }
          if (item.sceneFloorId) {
            relationSceneRooms.push(item.sceneFloorId)
          }
          if (item.sceneRoomId) {
            relationSceneRooms.push(item.sceneRoomId)
          }
          return relationSceneRooms
        })
        await this.relationRoomChangeHandler(relationData, formData['relationSceneRoom_' + key])
        this.formData['relationDevice_' + key] = valueList.map(item => item.targetId)
        if (relationData.value === '1') {
          this.relationDeviceChangeHandler(relationData, formData['relationDevice_' + key])
        } else {
          this.relationCarbonSinkDataChangeHandler(relationData, formData['relationDevice_' + key])
        }
      }
    },
    relationDeviceDeleteHandler(item, dataItem) {
      this.formData['relationDevice_' + item.value] = this.formData['relationDevice_' + item.value].filter(item => item !== dataItem.targetId)
      if (item.value === '1') {
        this.relationDeviceChangeHandler(item, this.formData['relationDevice_' + item.value])
      } else {
        this.relationCarbonSinkDataChangeHandler(item, this.formData['relationDevice_' + item.value])
      }
    },
    relationDeviceChangeHandler(item, values) {
      const list = []
      if(values?.length > 0) {
        values.forEach(deviceId => {
          const device = this.deviceInfo[item.value].find(item => item.id === deviceId)
          let fullRoomName = ''
          const roomTree = this.roomInfo[this.formData['relationSceneProject_' + item.value]]
          roomTree?.forEach(edifice => {
            if (edifice.value === device.sceneEdificeId) {
              fullRoomName += edifice.label
              if (edifice.children) {
                edifice.children.forEach(floor => {
                  if (floor.value === device.sceneFloorId) {
                    fullRoomName += floor.label
                    if (floor.children) {
                      floor.children.forEach(room => {
                        if (room.value === device.sceneRoomId) {
                          fullRoomName += room.label
                        }
                      })
                    }
                  }
                })
              }
            }
          })
          list.push({
            targetId: deviceId,
            dataType: item.value,
            sceneProjectId: device.sceneProjectId,
            sceneProjectName: this.projectList.find(item => item.id === device.sceneProjectId)?.projectName,
            fullRoomName: fullRoomName,
            sceneEdificeId: device.sceneEdificeId,
            sceneFloorId: device.sceneFloorId,
            sceneRoomId: device.sceneRoomId,
            deviceCode: device.deviceCode,
            deviceName: device.deviceName,
            meterTypeName: device.meterTypeName,
            staticsTypeName: device.staticsTypeName
          })
        })
      }
      this.relationDataTypeList.find(relationDataIem => relationDataIem.value === item.value).list = list
    },
    relationCarbonSinkDataChangeHandler(item, values) {
      debugger
      const list = []
      values.forEach(deviceId => {
        const carbonSink = this.deviceInfo[item.value].find(item => item.id === deviceId)
        list.push({
          targetId: carbonSink.id,
          dataType: item.value,
          typeName: carbonSink.typeName,
          carbonSinkName: carbonSink.carbonSinkIdName,
          sceneProjectId: carbonSink.sceneProjectId,
          sceneProjectName: this.projectList.find(item => item.id === carbonSink.sceneProjectId)?.projectName,
          fullRoomName: carbonSink.sceneInfoName,
          sceneEdificeId: carbonSink.sceneEdificeId,
          sceneFloorId: carbonSink.sceneFloorId,
          sceneRoomId: carbonSink.sceneRoomId
        })
      })
      this.relationDataTypeList.find(relationDataIem => relationDataIem.value === item.value).list = list
    },
    async relationRoomChangeHandler(item, values) {
      if (values != null && values.length > 0) {
        const sceneEdificeIds = []
        const sceneFloorIds = []
        const sceneRoomIds = []
        values.forEach(value => {
          if (value.length > 0 && !sceneEdificeIds.includes(value[0])) {
            sceneEdificeIds.push(value[0])
          }
          if (value.length > 1 && !sceneFloorIds.includes(value[1])) {
            sceneFloorIds.push(value[1])
          }
          if (value.length > 2 && !sceneRoomIds.includes(value[2])) {
            sceneRoomIds.push(value[2])
          }
        })
        const sceneEdificeId = Array.from(new Set(sceneEdificeIds)).join(',')
        const sceneFloorId = Array.from(new Set(sceneFloorIds)).join(',')
        const sceneRoomId = Array.from(new Set(sceneRoomIds)).join(',')
        let result = []
        if (item.value === '1') {
          result = this.formData.activityType === '1' ? await this.$api.meterDevice.queryMeterDeviceWithEmissionFactor({
              sceneEdificeId,
              sceneFloorId,
              sceneRoomId
            }) :
            await this.$api.meterDevice.queryMeterDeviceWithEmissionReductionFactor({
              sceneEdificeId,
              sceneFloorId,
              sceneRoomId
            })
        } else {
          result = await this.$api.carbonSink.queryList({
            sceneEdificeId,
            sceneFloorId,
            sceneRoomId
          })
        }
        let obj = { ...this.deviceInfo }
        obj[item.value] = result.data
        this.deviceInfo = obj
      } else {
        delete this.deviceInfo[item.value]
        delete this.formData['relationDevice_' + item.value]
        delete this.formData['relationSceneProject_' + item.value]
        const relationData = this.relationDataTypeList.find(relationData => relationData.value === item.value)
        if (relationData) {
          relationData.list = []
        }
      }
    },
    async relationProjectChangeHandler(item, id) {
      if (!this.roomInfo[item.value]) {
        let res = await api.queryRoomList({
          sceneProjectId: id,
          sortColumn: 'floorName',
          sortOrder: 'asc'
        })
        let obj = { ...this.roomInfo }
        obj[id] = parseSceneData(res.data)
        this.roomInfo = obj
      }
    },
    activityTypeChange() {
      const activityType = this.formData.activityType
      if (activityType === '1') { // 碳抵消活动
        const relationDataTypes = this.formList.find(item => item.prop === 'relationDataTypes')
        if (relationDataTypes) {
          relationDataTypes.optionList = relationDataTypes.optionList.filter(item => item.value !== '2')
          delete this.formData['relationDataType_2']
          this.relationDataTypeList = this.relationDataTypeList.filter(item => item.value !== '2')
        }
      } else {
        const relationDataTypes = this.formList.find(item => item.prop === 'relationDataTypes')
        if (relationDataTypes && relationDataTypes.optionList.find(item => item.value === '2') == null) {
          relationDataTypes.optionList.splice(1, 0, {
            label: '关联绿化',
            value: '2'
          })
        }
      }
    },
    relationDataTypesChange(relationDataType, selected) {
      if (selected) {
        if (relationDataType.value === '3') { // 其他类型
          this.formData.relationDataOthers = selected
        } else {
          let selectItem = this.relationDataTypeList.find(item => item.value === relationDataType.value)
          if (!selectItem) {
            this.relationDataTypeList.push({
              title: relationDataType.label,
              value: relationDataType.value,
              list: []
            })
          }
        }
      } else {
        this.relationDataTypeList = this.relationDataTypeList.filter(item => item.value !== relationDataType.value)
        if (relationDataType.value === '3') { // 其他类型
          this.formData.relationDataOthers = selected
        }
      }
    },
    /**
     * change事件
     */
    handlerSelectData(config) {
      const Ref = this.$refs[config.prop]
      if (Ref && config.isClosePop) {
        Ref.dropDownVisible = false
      }
      if (config.prop === 'activityType') {
        this.activityTypeChange()
      } else if (config.prop === 'relationDataTypes') {
        this.relationDataTypesChange()
      }
    },
    /**
     * 提交
     */
    submit(params) {
      const relationData = []
      if (this.relationDataTypeList.length > 0) {
        this.relationDataTypeList.forEach(item => {
          item.list.forEach((value) => {
            relationData.push(value)
          })
        })
      }
      params.relationDataJson = JSON.stringify(relationData)
      console.log(params, this.relationDataTypeList)
      this.$refs.form.validate(async (valid) => {
        if (valid) {
          const res = await this.$api.activityCarbonEmission[this.isAdd ? 'add' : 'update'](params)
          if (Number(res.code) === 1000) {
            this.$message.success(`${this.isAdd ? '新增' : '编辑'}成功！`)
            this.$emit('onFinish', 'carbonEmissionRange-add')
          }
        }
      })
    }
  }
}
</script>
<style lang="scss" scoped>
.relation-data-container {
  margin-left: 120px;

  .relation-item {
    margin-bottom: 12px;
  }

  .relation-title {
    border: 1px solid #DCDFE6;
    line-height: 32px;
    padding-left: 20px;
    font-size: 16px;
  }

  .relation-data {
    border: 1px solid #DCDFE6;
    padding: 12px 16px 0 16px;
  }

  .row-title {
    line-height: 28px;
    font-size: 14px;
    font-weight: 600;
    display: flex;
    gap: 2px;
  }

  .row-item {
    line-height: 34px;
    display: flex;
    gap: 2px;
    margin-bottom: 10px;

    .el-col:not(:last-child) {
      background: #DCDFE6;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
  }
}
</style>
